<?php


namespace App\Services\Repo;

use App\EmptyObject;
use App\Models\Group;
use App\Models\Project;
use App\Models\User;
use App\Models\WxClient;
use App\Services\HelpService;
use Auth;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use App\Services\Interfaces\RepoServiceInterface;
use Illuminate\Database\Eloquent\Model;


class ProjectRepo implements RepoServiceInterface
{
    /**
     * @param array|null $_options
     * @return Model
     * <code>
     *  $repo->create(['name' => '']);
     * </code>
     */
    public function create(array $_options = null):Model
    {
        $project = new Project();
        $project->group_id = $_options['group_id'];
        $project->title = $_options['title'];
        $project->users = $_options['users'];
        $project->wx_id = $_options['wx_id'];
        $project->plugins = null;
        $project->save();
        // 创建成功后 修改Wxclient的project_id,值为刚创建的项目id
        if (!is_null($project)) {
            foreach ($_options['wx_id'] as $wx_id){
                $wxClient = WxClient::find($wx_id);
                $wxClient->project_id = $project->id;
                $wxClient->save();
            }
        }
        return $project;
    }

    public function read($limit = 0)
    {
        $inputs = HelpService::get_filter();
        $user = Auth::User();
        $group_id = $user->group_id;
        if ($inputs && !empty($inputs['group']['_id'])) {
            //TODO:判断传入group_id权限
            $group_id = $inputs['group']['_id'];
        }
        if (!$group_id)
            return ['total' => 0, 'data' => []];
        $group = Group::find($group_id);
        if (is_null($group))
            return ['total' => 0, 'data' => []];
        $groups = $group->getLeafBy();
        $group_ids = [];
        if (is_array($groups)) {
            foreach ($groups as $group) {
                if (!is_null($group)) {
                    array_push($group_ids, $group->id);
                }
            }
        } else {
            array_push($group_ids, $groups->id);
        }

        //是否分配微信查询
        if (isset($inputs['isProject'])
            && in_array($inputs['isProject'], [0, 1])) {
            $project_group = Project::where([
                'group_id' => ['$in' => $group_ids],
                'wx_id' => ['$nin' => [[], null]],
            ])->get()->pluck('group_id')->all();
            if ($inputs['isProject']) {
                $group_ids = $project_group;
            } else {
                $group_ids = array_diff($group_ids, $project_group);
            }
        }
        $groups = Group::whereIn('_id', $group_ids)
            ->paginate(20);
        $projects = [];
        foreach ($groups as $group) {
            array_push($projects, $this->getProject($group));
        }
        $projects = new LengthAwarePaginator($projects,
            $groups->total(), 20, request()->input('page', 1));
        return $projects;
    }

    public function find(array $_filter):Model
    {
        $project = Project::find($_filter)->first();
        $managers = [];
        $users = [];
        $wxClients = [];
        $group = new Group();
        if (is_null($project)) {
            return new Project();
        }
        if ($project->users) {
            $total_users = User::whereIn('_id', $project->users)
                ->get();
            if ($total_users) {
                foreach ($total_users as $user) {
                    if ($user->isManager) {
                        array_push($managers, $user->name);
                    } else {
                        array_push($users, $user->name);
                    }
                }
            }
        }
        if ($project->wxClients) {
            $wxClients_temp = $project->wxClients;
            foreach ($wxClients_temp as $wxClient) {
                array_push($wxClients, [
                    '_id' => $wxClient->_id,
                    'nickName' => $wxClient->nickName,
                    'friendCount' => $wxClient->friendCount,
                ]);
            }
        }

        $project->users = $users;
        $project->managers = $managers;
        $project->wxClients = $wxClients;
        $roots = $group->getRootBy($project->group_id);
        $group = [];
        foreach ($roots as $root) {
            array_unshift($group, $root->name);
        }
        $project->group = $group;
        return $project;
    }

    public function update(array $_filter, array $_update_data):bool
    {
        $project = Project::find($_filter)->first();
        if(is_null($project)){
            return false;
        }
        if (isset($_update_data['wx_id'])) {
            $wx_id = $_update_data['wx_id'];
            $old_wx_id = $project->wx_id ?? [];
            $project_id = $project->id;
            $wx_diff = [];
            $add_wx = true;
            if (count($wx_id) > count($old_wx_id)) {
                $wx_diff
                    = $project->canAddWx(array_diff($wx_id, $old_wx_id));
                $wx_id = array_merge($old_wx_id, $wx_diff);
            } else if ((count($wx_id) < count($old_wx_id))) {
                $wx_diff
                    = $project->canDeleteWx(array_diff($old_wx_id, $wx_id));
                $wx_id = array_diff($old_wx_id, $wx_diff);
                $add_wx = false;
                $project_id = '';
            } else {
                $wx_diff = array_diff($old_wx_id, $wx_id);
                if ($wx_diff !== []) {
                    return false;
                }
            }
            $_update_data['wx_id'] = $wx_id;
            if ($wx_diff) {
                foreach ($wx_diff as $wx_id){
                    $wxClient = WxClient::find($wx_id);
                    if($add_wx) {
                        $wxClient->project_id = $project_id;
                    } else {
                        $wxClient->project_id = '';
                    }
                    $wxClient->save();
                }
            } else {
                return false;
            }
        }
        $attr = $project->getAttributes();
        foreach($attr as $k=>$v){
            if(isset($_update_data[$k])){
                $project->$k = $_update_data[$k];
            }
        }
        return $project->save();
    }

    public function delete(array $_filter):bool
    {
        // TODO: Implement delete() method.
    }

    public function getProject (Model $_group):Model
    {
        $project = Project::where('group_id', $_group->id)
            ->first();
        $managers = [];
        $users = [];
        $wxClients = [];
        if ($project) {
            if ($project->users) {
                $total_users = User::whereIn('_id', $project->users)
                    ->get();
                if ($total_users) {
                    foreach ($total_users as $user) {
                        if ($user->isManager) {
                            array_push($managers, $user->name);
                        } else {
                            array_push($users, $user->name);
                        }
                    }
                }
            }
            if ($project->wxClients) {
                $wxClients_temp = $project->wxClients;
                foreach ($wxClients_temp as $wxClient) {
                    array_push($wxClients, [
                        '_id' => $wxClient->_id,
                        'nickName' => $wxClient->nickName,
                        'friendCount' => $wxClient->friendCount,
                    ]);
                }
            }
        } else {
            $project = new Project();
            $project->_id = null;
            $project->group_id = $_group->id;
            $users = $this->getUsers($_group->id, 'name', false);
            $managers = $this->getUsers($_group->id, 'name', true);
        }
        $project->name = $_group->name;
        $project->users = $users;
        $project->managers = $managers;
        $project->wxClients = $wxClients;
        $roots = $_group->getRootBy($_group->id);
        $group = [];
        foreach ($roots as $root) {
            array_unshift($group, $root->name);
        }
        $project->group = $group;
        return $project;
    }

//    public function getManagers($_group_id, $field = '_id') {
//        return $managers = User::where([
//            'group_id' => $_group_id,
//            'isManager' => true,
//        ])->get()->pluck($field)->all();
//    }

    public function getUsers($_group_id, $field = '_id', $_isManager = null) {
        $query = User::where([
            'group_id' => $_group_id,
        ]);
        if (!is_null($_isManager)) {
            $query = $query->where('isManager', $_isManager);
        }
        return $query->pluck($field)->all();
    }
}
